/*
 * 	Flan.Zeng 2011-2016	http://git.oschina.net/signup?inviter=flan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.flan.stock.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;

/**
 * 自定义可以横向纵向滚动的ListView
 * @author flan
 * @since  2016年4月15日
 */
public class HVListView extends ListView{
	
	/** 偏移坐标 */
    private int mOffset = 0;
    /** 屏幕宽度 */
    private int screenWidth;
    /** 滚动View的宽度 */
    private int scrollWidth;
	/** 列头 */
    private LinearLayout listHead;
	/** 手势 */
    private GestureDetector mGesture;
    
    AttributeSet attrs;

	public HVListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mGesture = new GestureDetector(context, gestureListener);
		/*this.attrs = attrs;
		int l = attrs.getAttributeIntValue(android.R.attr.layout_width, 0);
		System.out.println("layout_width:"+l);*/
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		super.dispatchTouchEvent(ev);
		return mGesture.onTouchEvent(ev);
	}
	
	/**匿名内部类，处理监听到的手势事件*/
	private OnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener(){

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
			
			synchronized (HVListView.this) {
				int moveX = (int) distanceX;		//沿着X轴移动的距离
                int curX = listHead.getScrollX();	//当前X轴的滚动的位置
                if(screenWidth<=0)
                	screenWidth = getWidth();
                //System.out.println("滚动View的宽度:"+scrollWidth);
                int dx = moveX;
                
                //控制越界问题
                if (curX + moveX < 0)
                    dx = 0;
                if (curX + moveX + getScreenWidth() > scrollWidth){
                	dx = scrollWidth - getScreenWidth() - curX;
                }
                mOffset += dx;
                
                //根据手势滚动HVListView中每个Item视图
                for (int i = 0, j = getChildCount(); i < j; i++) {
                    View child = ((ViewGroup) getChildAt(i)).getChildAt(1);
                    if (child.getScrollX() != mOffset){
                    	child.scrollTo(mOffset, 0);
                    }
                }
                //滚动HVListView的表头
                listHead.scrollBy(dx, 0);
			}
			//当view确定自身已经不再适合现有的区域时，该view本身调用这个方法要求parent view
			//重新调用他的onMeasure onLayout来对重新设置自己位置
			requestLayout();
			
			return true;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
			return false;
		}

		@Override
		public boolean onDown(MotionEvent e) {
			return true;
		}
		
	};
	
	  /**
     * 获取屏幕可见范围内最大屏幕
     * @return
     */
    public int getScreenWidth() {
        if (screenWidth == 0) {
            screenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
            if (getChildAt(0) != null) {
            	//减去固定列的宽度
                screenWidth -= ((ViewGroup) getChildAt(0)).getChildAt(0).getMeasuredWidth();
            } else if (listHead != null) {
                //减去固定第一列
                screenWidth -= listHead.getChildAt(0).getMeasuredWidth();
            }
        }
        return screenWidth;
    }
    
    /** 获取列头偏移量 */
    public int getHeadScrollX() {
        return listHead.getScrollX();
    }

	public void setListHead(LinearLayout listHead) {
		this.listHead = listHead;
	}
	
	/**
	 * 设置可横向滚动的空间宽度
	 * 当最外层布局是RelativeLayout布局时必须设置，
	 * 不然无法获取可滚动空间的宽度
	 * @param scrollWidth 单位px
	 */
	public void setScrollWidth(int scrollWidth) {
		this.scrollWidth = scrollWidth;
	}
	
}
